package com.bird.system.adapter.menu.database

import com.bird.component.database.queryList
import com.bird.component.database.storeEntity
import com.bird.component.lang.util.nonnull
import com.bird.system.adapter.menu.database.dataobj.MenuDO
import com.bird.system.adapter.menu.database.mapper.MenuMapper
import com.bird.system.adapter.role.database.dataobj.RoleMenuDO
import com.bird.system.adapter.role.database.mapper.RoleMenuMapper
import com.bird.system.application.permission.RoleMenuRepository
import com.bird.system.domain.menu.MenuEntity
import com.bird.system.domain.menu.MenuRepository
import org.springframework.stereotype.Component

@Component
class MenuRepositoryMysqlImpl(
    private val menuMapper: MenuMapper,
    private val roleMenuMapper: RoleMenuMapper,
): MenuRepository, RoleMenuRepository {
    /**
     * 保存菜单
     */
    override fun save(menuEntity: MenuEntity) {
        //保存菜单-聚合根
        storeMenu(menuEntity)
    }
    /**
     * 持久化菜单
     */
    private fun storeMenu(menuEntity: MenuEntity) {
        menuMapper.storeEntity(menuEntity){ it.toMenuDO() }
    }

    override fun oneMenuById(menuId: Long): MenuEntity {
        TODO("Not yet implemented")
    }

    override fun listMenuByIds(ids: List<Long>): List<MenuEntity> {
        TODO("Not yet implemented")
    }

    override fun listMenuByParentId(parentId: Long): List<MenuEntity> {
        TODO("Not yet implemented")
    }

    /**
     * 根据角色id获取权限列表
     */
    override fun getPermListByRoleId(roleIds: List<Long>): List<String> {
        if (roleIds.isEmpty()) {
            return emptyList()
        }
        val roleMenus = roleMenuMapper.queryList {
            `in`(RoleMenuDO::roleId, roleIds)
        }
        if (roleMenus.isEmpty()) {
            return emptyList()
        }
        return menuMapper.queryList {
            `in`(MenuDO::id, roleMenus.map { it.menuId })
        }.filter {
            it.perm.nonnull()
        }.map {
            it.perm!!
        }
    }

    /**
     * 根据角色id获取权限列表
     */
    override fun getMenuListByRoleId(roleIds: List<Long>): List<MenuEntity> {
        if (roleIds.isEmpty()) {
            return emptyList()
        }
        val roleMenus = roleMenuMapper.queryList {
            `in`(RoleMenuDO::roleId, roleIds)
        }
        if (roleMenus.isEmpty()) {
            return emptyList()
        }
        return menuMapper.queryList {
            `in`(MenuDO::id, roleMenus.map { it.menuId })
        }.map {
            it.toEntity()
        }
    }
}